#include "LogWriter.h"

#define MAX_LOG_SIZE 1024 * 1024 * 10

using namespace std;

namespace LogWriter
{
	LogWriter::LogWriter(void)
	{
	}

	LogWriter::LogWriter(char *fn)
	{
		SECURITY_ATTRIBUTES  sa;
		sa.nLength = sizeof(SECURITY_ATTRIBUTES);
		sa.bInheritHandle = FALSE;
		HANDLE mut = CreateMutex(&sa, true, "Logger");
		outputBuffer = vector<char *>();
		fileName = fn;
	}

	LogWriter::~LogWriter(void)
	{
		HANDLE output = CreateFile(fileName,
			FILE_APPEND_DATA,
            FILE_SHARE_WRITE,
            NULL,
            OPEN_ALWAYS,
            FILE_ATTRIBUTE_NORMAL,
            NULL);

		for (int i = 0; i < outputBuffer.size(); i++)
		{
			DWORD bytesWritten;
			WriteFile(output, outputBuffer[i], strlen(outputBuffer[i]), &bytesWritten, 0);
		}
		CloseHandle(output);
		ReleaseMutex(mutex);
	}

	char* LogWriter::getTimeStamp()
	{
		char *tString = new char [80];
		time_t t = time (0);
		struct  tm* today = localtime (&t);
		strftime(tString, 80, "%d/%m/%Y %H:%M:%S", today);
		return tString;
	}

	void LogWriter::Log(LogWriter::errorLevel level, char *msg)
	{
		char *logLevel = new char[10];
		char *timeStamp = getTimeStamp();
		switch(level)
		{
		case 0:
			logLevel =  "FATAL";
			break;
		case 1:
			logLevel = "WARNING";
			break;
		case 2:
			logLevel =  "DEBUG";
			break;
		case 3:
			logLevel =  "INFO";
			break;
		}
		char *buffer = new char[strlen(msg) + 32];
		sprintf(buffer, "%s %s %s\r\n", timeStamp, logLevel, msg);
		outputBuffer.push_back(buffer);
	}

	void LogWriter::Warn(char *format, ...)
	{
		char *msg = new char[255];		
		va_list argList;
		va_start(argList, format);
		vsnprintf (msg, 100, format, argList);
		va_end(argList);
		return Log(WARN, msg);
	}

	void LogWriter::Debug(char *format, ...)
	{
		char *msg = new char[255];		
		va_list argList;
		va_start(argList, format);
		vsnprintf (msg, 100, format, argList);
		va_end(argList);
		return Log(DEBUG, msg);
	}

	void LogWriter::Fatal(char *format, ...)
	{
		char *msg = new char[255];		
		va_list argList;
		va_start(argList, format);
		vsnprintf (msg, 100, format, argList);
		va_end(argList);
		return Log(FATAL, msg);
	}

	void LogWriter::Info(char *format, ...)
	{
		char *msg = new char[255];		
		va_list argList;
		va_start(argList, format);
		vsnprintf (msg, 100, format, argList);
		va_end(argList);
		return Log(INFO, msg);
	}
}